package com.hd.trans.loader;

import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContentResolverCompat;

import com.hd.trans.db.bean.MediaItem;
import com.hd.trans.files.bean.Album;
import com.hd.trans.files.bean.MediaOptions;
import com.hd.trans.files.bean.MimeType;
import com.hd.trans.utils.SelectionUtil;

import java.util.ArrayList;
import java.util.List;

/**
 * @author qianjujun
 * @email qianjujun@163.com
 * @createTime 2020/9/25 17:34
 * @describe
 */
public class MediaLoader {

    private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
    private static String ORDER_BY = MediaStore.Video.Media.DATE_MODIFIED + " DESC";
    private static final String[] PROJECTION = {
            MediaStore.Files.FileColumns._ID,
            MediaStore.MediaColumns.DISPLAY_NAME,
            MediaStore.MediaColumns.MIME_TYPE,
            MediaStore.MediaColumns.SIZE,
            "duration",
            MediaStore.MediaColumns.WIDTH,
            MediaStore.MediaColumns.HEIGHT,
            MediaStore.MediaColumns.DATA};


    private Context context;
    private Uri uri;
    private String[] projection;
    private String selection;
    private String[] selectionArgs;
    private String sortOrder;

    public MediaLoader(@NonNull Context context, @Nullable String[] projection, @Nullable String selection) {
        this.context = context;
        this.uri = QUERY_URI;
        this.projection = projection;
        this.selection = selection;
        this.selectionArgs = null;
        this.sortOrder = ORDER_BY;
    }


    public static MediaLoader getInstance(Context context, MediaOptions mediaOptions, Album album) {
        String orderBy = MediaStore.Images.Media.DATE_MODIFIED + " DESC";

        String[] projection = PROJECTION;
        StringBuilder selection = new StringBuilder();
        if (mediaOptions.getMediaType() == MediaOptions.TYPE_VIDEO) {
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE);
            selection.append("=");
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
            List<MimeType> list = mediaOptions.getIncludeMimeType();
            SelectionUtil.handlerInclude(selection, list);
            list = mediaOptions.getExcludeMimeType();
            SelectionUtil.handlerExclude(selection, list);
            orderBy = MediaStore.Video.Media.DATE_MODIFIED + " DESC";
        } else if (mediaOptions.getMediaType() == MediaOptions.TYPE_IMAGE) {
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE);
            selection.append("=");
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
            List<MimeType> list = mediaOptions.getIncludeMimeType();
            SelectionUtil.handlerInclude(selection, list);
            list = mediaOptions.getExcludeMimeType();
            SelectionUtil.handlerExclude(selection, list);
        } else {
            selection.append("(");
            selection.append("(");
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE);
            selection.append("=");
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
            selection.append(" AND mime_type = 'video/mp4'");
            selection.append(")");

            selection.append(" OR ");
            selection.append("(");
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE);
            selection.append("=");
            selection.append(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
            List<MimeType> list = mediaOptions.getIncludeMimeType();
            SelectionUtil.handlerInclude(selection, list);
            list = mediaOptions.getExcludeMimeType();
            SelectionUtil.handlerExclude(selection, list);
            selection.append(")");

            selection.append(")");
        }

        if (!TextUtils.equals("-1", album.getmId())) {
            selection.append(" AND bucket_id =");
            selection.append(album.getmId());
        }

        selection.append(" AND ");
        selection.append(MediaStore.MediaColumns.SIZE);
        selection.append(">0");

        if (mediaOptions.getMediaType() == MediaOptions.TYPE_IMAGE) {
            selection.append(" AND IFNULL(");
            selection.append(MediaStore.MediaColumns.WIDTH);
            selection.append(",0)");
            selection.append("<=IFNULL(");
            selection.append(MediaStore.MediaColumns.HEIGHT);
            selection.append(",0)");
            selection.append("*10");
            selection.append(" AND IFNULL(");
            selection.append(MediaStore.MediaColumns.HEIGHT);
            selection.append(",0)");
            selection.append("<=IFNULL(");
            selection.append(MediaStore.MediaColumns.WIDTH);
            selection.append(",0)");
            selection.append("*10");
        }
        /*
         * dng图片用mimeType无法过滤 只能用path
         */
        selection.append(" AND lower(")
                .append(MediaStore.MediaColumns.DATA)
                .append(") NOT LIKE  '%.dng'");

        MediaLoader mediaLoader = new MediaLoader(context, projection, selection.toString());
        mediaLoader.sortOrder = orderBy;
        return mediaLoader;

    }


    public List<MediaItem> load() throws Exception {
        Cursor cursor = ContentResolverCompat.query(context.getContentResolver(), uri, projection, selection, selectionArgs, sortOrder, null);
        return convert(cursor);
    }


    protected List<MediaItem> convert(Cursor cursor) {
        List<MediaItem> list = new ArrayList<>();
        MediaItem mediaItem;
        while (cursor.moveToNext()) {
            mediaItem = new MediaItem();
            mediaItem.setId(cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID)));
            mediaItem.setMimeType(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE)));
            mediaItem.setDuration(cursor.getLong(cursor.getColumnIndex("duration")));
            mediaItem.setSize(cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns.SIZE)));
            mediaItem.setWidth(cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns.WIDTH)));
            mediaItem.setHeight(cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns.HEIGHT)));
            mediaItem.setPath(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
            Uri contentUri;
            if (MimeType.isImage(mediaItem.getMimeType())) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if (MimeType.isVideo(mediaItem.getMimeType())) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else {
                contentUri = MediaStore.Files.getContentUri("external");
            }
            mediaItem.setUri(ContentUris.withAppendedId(contentUri, mediaItem.getId()));
            list.add(mediaItem);
        }
        return list;
    }

    public static String getPath(long id) {
        return QUERY_URI.buildUpon().appendPath(String.valueOf(id)).build().toString();
    }

}
